import 'package:flutter/material.dart';

class StaggerAnimationRoute extends StatefulWidget {
  const StaggerAnimationRoute({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _StaggerAnimationRouteState();
}

class _StaggerAnimationRouteState extends State<StaggerAnimationRoute>
    with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(duration: const Duration(seconds: 3), vsync: this);
  }

  _playAnimation() async {
    try {
      await _controller.forward().orCancel;
      await _controller.reverse().orCancel;
    } on TickerCanceled {
      // the animation got canceled, probably because we were disposed
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('交织动画'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            const SizedBox(height: 10),
            ElevatedButton(
              onPressed: () => _playAnimation(),
              child: const Text("start animation"),
            ),
            const SizedBox(height: 10),
            Container(
              width: 300.0,
              height: 300.0,
              decoration: BoxDecoration(
                color: Colors.black.withOpacity(0.1),
                border: Border.all(
                  color: Colors.black.withOpacity(0.5),
                ),
              ),
              child: StaggerAnimation(
                controller: _controller,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class StaggerAnimation extends StatelessWidget {
  final Animation<double> controller;

  late final Animation<double> height;

  late final Animation<EdgeInsets> padding;

  late final Animation<Color?> color;

  StaggerAnimation({Key? key, required this.controller}) : super(key: key) {
    height = Tween<double>(begin: 0.0, end: 300.0).animate(CurvedAnimation(
        parent: controller,
        curve: const Interval(0.0, 0.6, curve: Curves.ease)));

    color = ColorTween(begin: Colors.grey, end: Colors.red).animate(
        CurvedAnimation(
            parent: controller,
            curve: const Interval(0.0, 0.6, curve: Curves.ease)));

    padding = Tween<EdgeInsets>(
      begin: const EdgeInsets.only(left: 0.0),
      end: const EdgeInsets.only(left: 100.0),
    ).animate(CurvedAnimation(
        parent: controller,
        curve: const Interval(
          0.6,
          1.0,
          curve: Curves.ease,
        )));
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      builder: (BuildContext context, child) {
        return Container(
          alignment: Alignment.bottomCenter,
          padding: padding.value,
          child: Container(
            color: color.value,
            width: 50.0,
            height: height.value,
          ),
        );
      },
      animation: controller,
    );
  }
}
